<?php

  /**
   *  Copyright 2009 Sven Wesley
   * 
   *  This API is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation, either version 3 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  The GNU GPL License is found at http://www.gnu.org/licenses/gpl.txt
   * 
   *  version 0.1
   *
   **/   

  //$WS_URL = "http://localhost/api/soap/?wsdl"; 
  //$WS_URL = "http://192.168.50.3/magento/index.php/api/soap/?wsdl"; 
  $WS_URL = "http://192.168.50.3/magento/index.php/api/v2_soap/?wsdl";
  
  //FOR TEST
  //$_POST["api_servicecall"] = "
  // <request>
  //    <call>login</call>
  //    <user>webserviceuser</user>
  //    <apikey>password123</apikey>
  // </request>";
   
  //$_POST["api_servicecall"] = 
  //"<request>
  //   <call>product.list</call>
  //   <session>add-your-session-variable-here</session>
  //   <arg>
  //     <sku>
  //       <like>DRO%</like>
  //     </sku>
  //   </arg>
  // </request>";
  
  //$_POST["api_servicecall"] = 
  //"<request>
  //   <call>product.info</call>
  //   <session>add-your-session-variable-here</session>
  //   <arg>199</arg>
  // </request>";  
  
  //$_POST["api_servicecall"] = 
  //"<request>
  //   <call>multicall</call>
  //   <session>add-your-session-variable-here</session>
  //   <arg>
  //     <call1>
  //        <resource>directory_country.list</resource>
  //     </call1>
  //     <call2>
  //        <resource>product.info</resource>
  //        <arg>155</arg>
  //     </call2>
  //     <call3>
  //        <resource>product.list</resource>
  //        <arg>
  //           <sku>
  //             <like>DRO006</like>
  //           </sku>
  //        </arg>
  //     </call3>
  //   </arg>
  // </request>";  
  
  //$_POST["api_servicecall"] = "
  //<request>
  //   <call>endsession</call>
  //   <session>add-your-session-variable-here</session>
  //</request>";
  
  if (!array_key_exists("api_servicecall", $_POST)) {exit;}
  
  $ARG_ARRAY = xml2array($_POST["api_servicecall"]);
  $API_CALL = $ARG_ARRAY["request"]["call"];
  $soap = new SoapClient($WS_URL); 
  $resultArray = array();
  
  //FOR DEBUGGING, can be helpful to see what the API really received.
  //$fh = fopen('req.txt', 'w') or die("can't open file");
  //fwrite($fh, $_POST["api_servicecall"]);
  //fclose($fh);
  
  
  //Make the selected soap call
  try {
    if ($API_CALL === "login") {
       $resultArray["login"] = $soap->login($ARG_ARRAY["request"]["user"], $ARG_ARRAY["request"]["apikey"]);
    } elseif ($API_CALL === "endsession") {
       $resultArray["endsession"] = $soap->endsession($ARG_ARRAY["request"]["sessionId"]);
    } elseif ($API_CALL === "multicall") {
       //prepare the arguments list from the request array to a usable format.
       $requestArr = array();
       foreach($ARG_ARRAY["request"]["arg"] as $mCall) {
          if (!array_key_exists("arg",$mCall)) {
              array_push($requestArr, array($mCall["resource"]));
          } elseif (array_key_exists("arg",$mCall) && is_assoc($mCall["arg"])) {
              array_push($requestArr, array($mCall["resource"], array($mCall["arg"])));
          } else {
              array_push($requestArr, array($mCall["resource"], $mCall["arg"]));
          }
       }
       $resultArray["multicall"] = $soap->multicall($ARG_ARRAY["request"]["sessionId"], $requestArr);
    } elseif ($API_CALL === "catalogCategoryInfo") {
       $resultArray["call"] = $soap->catalogCategoryInfo($ARG_ARRAY["request"]["sessionId"], $ARG_ARRAY["request"]["categoryId"]);
    } else {
       if (is_assoc($ARG_ARRAY["request"]["arg"])) {
          $resultArray["call"] = $soap->call($ARG_ARRAY["request"]["sessionId"], $API_CALL, array($ARG_ARRAY["request"]["arg"])); 
       } else {
          $resultArray["call"] = $soap->call($ARG_ARRAY["request"]["sessionId"], $API_CALL, $ARG_ARRAY["request"]["arg"]);
       }
    }

    $xml = new XMLWriter();
    $xml->openURI("php://output");
    $xml->startDocument("1.0");
    $xml->setIndent(3);
    
    if (is_assoc($resultArray)) {
      resultToXml("response", $resultArray, $xml);
    } else {
      foreach($resultArray as $a) {
		if (is_assoc($a)) {
		  resultToXml("response", $a, $xml);
		} 
        resultToXml("response", $a, $xml);
      }
    }
    
    $xml->endDocument();
    $xml->flush();
    
  } catch (Exception $e) {
     echo "<error>".$e->getMessage()."</error>";
  }
  
  
  
  
  
  function is_assoc($var) { 
    return is_array($var) && array_keys($var)!==range(0,sizeof($var)-1); 
  } 
  
  
  function resultToXml($responseName, $associativeArr, $xml) {
    $xml->startElement($responseName);
    arrayToXml($associativeArr, $xml);
    $xml->endElement();
  }
  
  
  function arrayToXml($array, $xml) {
    foreach($array as $key=>$value) {      
      //Make some cleaning, no numericals or odd characters.
      if (is_numeric($key)) { $key = "element";}  //{ $key = "element_".$key; } //uncomment this to get element_x for arrays.
      $key = preg_replace("/[^a-zA-Z0-9_\.]/i", "", $key);
      //If this is a nested array, call myself.
      if (is_array($value)) {
        $xml->startElement($key);
        arrayToXml($value, $xml);
        $xml->endElement();
      } else {
        $xml->writeElement($key, $value); 
      }
    }  
  }
  
  
  function xml2array($xml) {
        $xmlArray = array();
        $regexp = "/<(\w+)\s*([^\/>]*)\s*(?:\/>|>(.*)<\/\s*\\1\s*>)/s";
        preg_match_all($regexp, $xml, $elements);
        foreach ($elements[1] as $ie => $element) {
          if (preg_match($regexp, $elements[3][$ie]))
            $xmlArray[$element] = xml2array($elements[3][$ie]);
          else if ($elements[3][$ie]) {
            $xmlArray[$element] = trim($elements[3][$ie]);
          }
        }
        return $xmlArray;
  }
  
?>
